package com.ballyza;

import com.ballyza.gals.LexicalError;
import com.ballyza.gals.SemanticError;
import com.ballyza.gals.Semantico;
import com.ballyza.gals.Sintatico;
import com.ballyza.gals.SyntaticError;

public class BallyzaSyntactic {

	private final BallyzaLexical lexical;
	private final Sintatico anallyzer;
	private final CompileResult result;

	private Semantico semantico;

	public BallyzaSyntactic(BallyzaLexical lexical, CompileResult result) {
		this(lexical, result, false);
	}

	public BallyzaSyntactic(BallyzaLexical lexical, CompileResult result,
			boolean executeSemantic) {
		this.lexical = lexical;

		anallyzer = new Sintatico(executeSemantic);

		this.result = result;
	}

	public void start() {
		String nomeArquivo = "programa";
		try {
			anallyzer.parse(lexical.getLexico(), semantico = new Semantico(
					nomeArquivo));
		} catch (LexicalError e) {
			int linha = lexical.getText().substring(0, e.getPosition())
					.split("\n").length;
			String errorMessage = "Erro na linha "
					.concat(String.valueOf(linha));
			errorMessage = errorMessage.concat(" - ");
			errorMessage = errorMessage.concat(String.valueOf(e.getCharacter())
					+ " ");
			errorMessage = errorMessage.concat(e.getMessage());

			result.setErrorMessage(errorMessage);
			result.setSuccess(false);

		} catch (SyntaticError e) {
			String lexeme = e.getLexeme();
			if (lexeme.equals("$"))
				lexeme = "fim de programa";
			int endIndex = e.getPosition();
			if(endIndex + 1 < lexical.getText().length()) {
				endIndex++;
			}
			int linha = lexical.getText().substring(0, endIndex)
					.split("\n").length;

			String errorMessage = "Erro na linha " + String.valueOf(linha)
					+ " - ";
			errorMessage = errorMessage
					+ "encontrado ".concat(lexeme).concat(". ")
							.concat(e.getMessage());
			this.result.setErrorMessage(errorMessage);
			this.result.setSuccess(false);
		} catch (SemanticError e) {
			int linha = lexical.getText().substring(0, e.getPosition())
					.split("\n").length;

			String errorMessage = "Erro na linha "
					.concat(String.valueOf(linha));
			errorMessage = errorMessage.concat(" - ");
			errorMessage = errorMessage.concat(e.getToken() + " ");
			errorMessage = errorMessage.concat(e.getMessage());

			result.setSuccess(false);
			result.setErrorMessage(e.getMessage());
		}
	}

	public Semantico getSemantico() {
		return semantico;
	}

	public void setSemantico(Semantico semantico) {
		this.semantico = semantico;
	}

}